/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controladores;

import controladores.exceptions.IllegalOrphanException;
import controladores.exceptions.NonexistentEntityException;
import controladores.exceptions.PreexistingEntityException;
import entidades.TipoEtapa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.Etapa;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Andres
 */
public class TipoEtapaJpaController {

    public TipoEtapaJpaController() {
        emf = Persistence.createEntityManagerFactory("proyectoCongresoPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(TipoEtapa tipoEtapa) throws PreexistingEntityException, Exception {
        if (tipoEtapa.getEtapaList() == null) {
            tipoEtapa.setEtapaList(new ArrayList<Etapa>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Etapa> attachedEtapaList = new ArrayList<Etapa>();
            for (Etapa etapaListEtapaToAttach : tipoEtapa.getEtapaList()) {
                etapaListEtapaToAttach = em.getReference(etapaListEtapaToAttach.getClass(), etapaListEtapaToAttach.getCodigoetapa());
                attachedEtapaList.add(etapaListEtapaToAttach);
            }
            tipoEtapa.setEtapaList(attachedEtapaList);
            em.persist(tipoEtapa);
            for (Etapa etapaListEtapa : tipoEtapa.getEtapaList()) {
                TipoEtapa oldTipoEtapaOfEtapaListEtapa = etapaListEtapa.getTipoEtapa();
                etapaListEtapa.setTipoEtapa(tipoEtapa);
                etapaListEtapa = em.merge(etapaListEtapa);
                if (oldTipoEtapaOfEtapaListEtapa != null) {
                    oldTipoEtapaOfEtapaListEtapa.getEtapaList().remove(etapaListEtapa);
                    oldTipoEtapaOfEtapaListEtapa = em.merge(oldTipoEtapaOfEtapaListEtapa);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findTipoEtapa(tipoEtapa.getIdTipoEtapa()) != null) {
                throw new PreexistingEntityException("TipoEtapa " + tipoEtapa + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(TipoEtapa tipoEtapa) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoEtapa persistentTipoEtapa = em.find(TipoEtapa.class, tipoEtapa.getIdTipoEtapa());
            List<Etapa> etapaListOld = persistentTipoEtapa.getEtapaList();
            List<Etapa> etapaListNew = tipoEtapa.getEtapaList();
            List<String> illegalOrphanMessages = null;
            for (Etapa etapaListOldEtapa : etapaListOld) {
                if (!etapaListNew.contains(etapaListOldEtapa)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Etapa " + etapaListOldEtapa + " since its tipoEtapa field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            List<Etapa> attachedEtapaListNew = new ArrayList<Etapa>();
            for (Etapa etapaListNewEtapaToAttach : etapaListNew) {
                etapaListNewEtapaToAttach = em.getReference(etapaListNewEtapaToAttach.getClass(), etapaListNewEtapaToAttach.getCodigoetapa());
                attachedEtapaListNew.add(etapaListNewEtapaToAttach);
            }
            etapaListNew = attachedEtapaListNew;
            tipoEtapa.setEtapaList(etapaListNew);
            tipoEtapa = em.merge(tipoEtapa);
            for (Etapa etapaListNewEtapa : etapaListNew) {
                if (!etapaListOld.contains(etapaListNewEtapa)) {
                    TipoEtapa oldTipoEtapaOfEtapaListNewEtapa = etapaListNewEtapa.getTipoEtapa();
                    etapaListNewEtapa.setTipoEtapa(tipoEtapa);
                    etapaListNewEtapa = em.merge(etapaListNewEtapa);
                    if (oldTipoEtapaOfEtapaListNewEtapa != null && !oldTipoEtapaOfEtapaListNewEtapa.equals(tipoEtapa)) {
                        oldTipoEtapaOfEtapaListNewEtapa.getEtapaList().remove(etapaListNewEtapa);
                        oldTipoEtapaOfEtapaListNewEtapa = em.merge(oldTipoEtapaOfEtapaListNewEtapa);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Short id = tipoEtapa.getIdTipoEtapa();
                if (findTipoEtapa(id) == null) {
                    throw new NonexistentEntityException("The tipoEtapa with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Short id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoEtapa tipoEtapa;
            try {
                tipoEtapa = em.getReference(TipoEtapa.class, id);
                tipoEtapa.getIdTipoEtapa();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The tipoEtapa with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Etapa> etapaListOrphanCheck = tipoEtapa.getEtapaList();
            for (Etapa etapaListOrphanCheckEtapa : etapaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This TipoEtapa (" + tipoEtapa + ") cannot be destroyed since the Etapa " + etapaListOrphanCheckEtapa + " in its etapaList field has a non-nullable tipoEtapa field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(tipoEtapa);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<TipoEtapa> findTipoEtapaEntities() {
        return findTipoEtapaEntities(true, -1, -1);
    }

    public List<TipoEtapa> findTipoEtapaEntities(int maxResults, int firstResult) {
        return findTipoEtapaEntities(false, maxResults, firstResult);
    }

    private List<TipoEtapa> findTipoEtapaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(TipoEtapa.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public TipoEtapa findTipoEtapa(Short id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(TipoEtapa.class, id);
        } finally {
            em.close();
        }
    }

    public int getTipoEtapaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<TipoEtapa> rt = cq.from(TipoEtapa.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
